package com.zfzs.post.service.impl;

import com.zfzs.post.exception.BadRequestException;
import com.zfzs.post.model.dto.TerminalTypeIdDTO;
import com.zfzs.post.model.vo.PolicyInfoVO;
import com.zfzs.post.model.vo.PolicyKindVO;
import com.zfzs.post.model.vo.PolicyVO;
import com.zfzs.post.modules.agent.domain.Agent;
import com.zfzs.post.modules.agent.domain.PolicyDivided;
import com.zfzs.post.modules.agent.service.AgentService;
import com.zfzs.post.modules.agent.service.PolicyDividedService;
import com.zfzs.post.modules.agent.service.dto.AgentDTO;
import com.zfzs.post.modules.policy.domain.*;
import com.zfzs.post.modules.policy.service.PolicyInfoService;
import com.zfzs.post.modules.policy.service.PolicyTypeService;
import com.zfzs.post.modules.post.domain.TerminalType;
import com.zfzs.post.modules.post.service.TerminalTypeService;
import com.zfzs.post.service.JwtUserDetailsService;
import com.zfzs.post.service.PolicyService;
import com.zfzs.post.utils.CloneUtils;
import com.zfzs.post.utils.JsonUtils;
import com.zfzs.post.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * 政策设置
 *
 * @author: ck
 * @create: 2019-09-26 10:35
 **/
@Service
public class PolicyServiceImpl implements PolicyService {

    @Autowired
    private PolicyTypeService policyTypeService;
    @Autowired
    private PolicyInfoService policyInfoService;
    @Autowired
    private TerminalTypeService terminalTypeService;
    @Autowired
    private JwtUserDetailsService jwtUserDetailsService;
    @Autowired
    private AgentService agentService;
    @Autowired
    private PolicyDividedService policyDividedService;

    @Override
    public Map<String, Object> queryPolicyInfo(TerminalTypeIdDTO dto) {
        Map<String, Object> map = new HashMap<>();
        Boolean isSetting = false;
        Long terminalTypeId = dto.getTerminalTypeId();
        Long agentId = dto.getAgentId();
        if (agentId == null) {
            throw new BadRequestException("agentId不能为空");
        }
        //获取登录人信息
        AgentDTO agentDTO = jwtUserDetailsService.getAgentInfo();
        //查询是否是直属人
        Boolean isDirectly = agentService.isDirectly(agentId, agentDTO.getId());
        if (!isDirectly) {
            throw new BadRequestException("您选择的代理商不是您的直属下级");
        }
        //当前人登录的政策
        PolicyInfo policyInfo = new PolicyInfo();
        policyInfo.setTerminalTypeId(terminalTypeId);
        policyInfo.setAgentId(agentDTO.getId());
        PolicyInfo p = policyInfoService.findOne(policyInfo);
        //搜索人的政策
        PolicyInfo belowPolicy = new PolicyInfo();
        belowPolicy.setTerminalTypeId(terminalTypeId);
        belowPolicy.setAgentId(agentId);
        PolicyInfo belowPolicyInfo = policyInfoService.findOne(belowPolicy);
        List<PolicyKind> belowKindList = new ArrayList<>();
        if (belowPolicyInfo != null) {
            isSetting = true;
            belowKindList = belowPolicyInfo.getList();
        }
        PolicyInfoVO vo = CloneUtils.clone(p, PolicyInfoVO.class);
        List<PolicyKindVO> pidPolicyList = CloneUtils.batchClone(p.getList(), PolicyKindVO.class);
        //按着Store降序
        vo.setPidPolicyList(pidPolicyList);
        /***************************  开始封装数据   ********************************/
        TerminalType typeInfo = terminalTypeService.findById(terminalTypeId);
        if (typeInfo == null) {
            throw new BadRequestException("没有查询到终端类型配置");
        }
        if (typeInfo.getStatus().intValue() != 0) {
            throw new BadRequestException("此终端已被禁用");
        }
        vo.setPostName(typeInfo.getTerminalName());
        //父政策配置
        for (int i = 0; i < pidPolicyList.size(); i++) {
            String id = pidPolicyList.get(i).getId();
            //查询父政策名称
            PolicyType policyType = policyTypeService.findById(id);
            if (policyType == null) {
                throw new BadRequestException("没有查询到政策设置");
            }
            if (!policyType.getStatus().equals("0")) {
                throw new BadRequestException("此终端政策已被禁用");
            }
            pidPolicyList.get(i).setName(policyType.getPolicyTypeName());
            //拷贝系统的子政策数据
            List<PolicyVO> childPolicyList = CloneUtils.batchClone(p.getList().get(i).getPolicyList(), PolicyVO.class);
            //按着Store降序
            Collections.sort(childPolicyList);
            pidPolicyList.get(i).setChilPpolicyList(childPolicyList);
            List<PolicyTypeInfo> typeList = policyType.getList();
            //自己的子政策数据
            for (int j = 0; j < childPolicyList.size(); j++) {
                String typeId = childPolicyList.get(j).getPolicyTypeId();
                for (PolicyTypeInfo policyTypeInfo : typeList) {
                    String childId = policyTypeInfo.getTypeId();
                    //自己有的政策ID对比
                    if (childId.equals(typeId)) {
                        String typeName = policyTypeInfo.getName();
                        childPolicyList.get(j).setName(typeName);
                        //查询下级设置人的设置金额 没有为0
                        String settingAmount = settingAmount(belowKindList, id, typeId);
                        childPolicyList.get(j).setSettingAmount(settingAmount);
                        //添加子政策名称
                        pidPolicyList.get(i).getChilPpolicyList().get(j).setName(typeName);
                    }
                }
            }
        }
        //降序排序
        Collections.sort(vo.getPidPolicyList());
        map.put("vo", vo);
        map.put("isSetting", isSetting);
        return map;
    }

    private String settingAmount(List<PolicyKind> list, String pidId, String childId) {
        for (int i = 0; i < list.size(); i++) {
            //查询父级
            String id = list.get(i).getId();
            if (StringUtils.equals(id, pidId)) {
                List<Policy> policyList = list.get(i).getPolicyList();
                //查询子级
                for (int j = 0; j < policyList.size(); j++) {
                    String policyTypeId = policyList.get(j).getPolicyTypeId();
                    if (StringUtils.equals(policyTypeId, childId)) {
                        if (StringUtils.isBlank(policyList.get(j).getAmount())) {
                            return "0";
                        }
                        return policyList.get(j).getAmount();
                    }
                }
            }
        }
        return "0";
    }

    @Override
    public Map<String, Object> isSettingPolicy(TerminalTypeIdDTO dto) {
        Map<String, Object> map = new HashMap<>();
        AgentDTO agent = jwtUserDetailsService.getAgentInfo();
        Long terminalTypeId = dto.getTerminalTypeId();
        PolicyInfo policyInfo = new PolicyInfo();
        policyInfo.setTerminalTypeId(terminalTypeId);
        policyInfo.setAgentId(agent.getId());
        PolicyInfo p = policyInfoService.findOne(policyInfo);
        //查询上级人信息
        Agent pidAgent = agentService.findById(agent.getPidId());
        String phone = "";
        if (pidAgent != null) {
            phone = pidAgent.getPhone();
        }
        map.put("phone", phone);
        //没有设置的权限
        map.put("isSetting", p != null);
        return map;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setPolicyInfo(PolicyInfo policyInfo) {
        System.out.println("===========政策设置开始=========");
        System.out.println(JsonUtils.toJson(policyInfo));

        Long agentId = policyInfo.getAgentId();
        //获取登录人信息
        AgentDTO agentDTO = jwtUserDetailsService.getAgentInfo();
        Long channelId = agentDTO.getChannelId();
        //终端类型信息
        Long terminalTypeId = policyInfo.getTerminalTypeId();
        //查询是否是直属人
        Boolean isDirectly = agentService.isDirectly(agentId, agentDTO.getId());
        if (!isDirectly) {
            throw new BadRequestException("您选择的代理商不是您的直属下级");
        }
        TerminalType typeInfo = terminalTypeService.findById(terminalTypeId);
        if (typeInfo == null) {
            throw new BadRequestException("没有查询到终端类型配置");
        }
        if (typeInfo.getStatus().intValue() != 0) {
            throw new BadRequestException("此终端已被禁用");
        }
        //校验是否有添加过政策
        if (policyInfoService.isPresence(agentId, terminalTypeId)) {
            throw new BadRequestException("此用户名下已经设置过此机器政策");
        }
        //父政策数据
        List<PolicyKind> pidVoList = policyInfo.getList();
        //计算所有的子政策信息
        List<PolicyDivided> dividedList = new ArrayList<>();

        for (int i = 0; i < pidVoList.size(); i++) {
            //进行政策匹配校验
            String pidIdVo = pidVoList.get(i).getId();
            //子政策数据
            List<Policy> pidPolicyVoList = pidVoList.get(i).getPolicyList();
            //查询上级人的政策信息
            PolicyInfo pidPolicyInfo = policyInfoService.findPolicyInfo(agentDTO.getId(), terminalTypeId);
            if (pidPolicyInfo == null) {
                throw new BadRequestException("没有查询到上级政策信息");
            }
            List<PolicyDivided> list = checkPidId(pidPolicyInfo.getList(), pidPolicyVoList, pidIdVo);
            //校验成功添加政策信息
            dividedList.addAll(list);
        }
        //录入数据
        for (int i = 0; i < dividedList.size(); i++) {
            PolicyDivided policyDivided = dividedList.get(i);
            policyDivided.setTerminalId(terminalTypeId);
            policyDivided.setAgentId(agentId);
            policyDivided.setChannelId(channelId);
            //校验是否存在
            PolicyDivided p = policyDividedService.getPolicyInfo(agentId, terminalTypeId, channelId, policyDivided.getNames());
            if (p == null) {
                policyDividedService.create(policyDivided);
            }
        }
        policyInfo.setCreateTime(new Date());
        policyInfo.setUpdateTime(new Date());
        policyInfo.setDistAgentId(agentDTO.getId());
        policyInfoService.save(policyInfo);

    }

    /**
     * 数据校验
     *
     * @param list          上级人的父政策
     * @param pidPolicyList 添加的子政策
     * @param id            添加的父政策ID
     */
    List<PolicyDivided> checkPidId(List<PolicyKind> list, List<Policy> pidPolicyList, String id) {
        int success = 0;
        List<PolicyDivided> dividedList = new ArrayList<>();
        for (PolicyKind p : list) {
            //配成功
            String parId = p.getId();
            if (StringUtils.equals(parId, id)) {
                success++;
                List<Policy> policyList = p.getPolicyList();
                for (Policy policy : pidPolicyList) {
                    String policyTypeId = policy.getPolicyTypeId();
                    int childCount = 0;
                    for (Policy pl : policyList) {
                        if (policyTypeId.equals(pl.getPolicyTypeId())) {
                            System.out.println("添加的子政策ID" + policyTypeId);
                            System.out.println("查询的子政策ID" + pl.getPolicyTypeId());
                            //校验参数值不能大于上一级
                            String amount = policy.getAmount(); //添加的子政策
                            String pidAmount = pl.getAmount(); //上级人子政策金额
                            System.out.println("-------------------------------------");
                            System.out.println("添加的子政策" + amount);
                            System.out.println("查询的上级子政策" + pidAmount);
                            System.out.println("设置的政策值不能大于您自己的政策值校验结果=====" + amount.compareTo(pidAmount));
                            System.out.println("是否是正常的数字校验结果=====" + !StringUtils.isNumber(amount));
                            //是否是正常的数字
                            //if (!StringUtils.isNumber(amount)) {
                            //   throw new BadRequestException("政策值请输入正确的金额值");
                            //}
                            //不允许设置为0
                            if (new BigDecimal(amount).compareTo(new BigDecimal(0.00)) == 0 || new BigDecimal(amount).compareTo(new BigDecimal(0.00)) == -1) {
                                throw new BadRequestException("设置的政策值不能小于0");
                            }
                            if (amount.compareTo(pidAmount) == 1) {
                                throw new BadRequestException("设置的政策值不能大于您自己的政策值");
                            }
                            //成功
                            childCount++;
                            PolicyDivided policyDivided = new PolicyDivided();
                            policyDivided.setNames(policy.getName());
                            policyDivided.setAmount(new BigDecimal(policy.getAmount()));
                            dividedList.add(policyDivided);

                        }
                    }
                    if (childCount != 1) {
                        throw new BadRequestException("政策设置异常");
                    }
                }
            }
        }
        if (success != 1) {
            throw new BadRequestException("政策设置异常");
        }
        return dividedList;
    }
}
